#!/usr/bin/env python3
# -*-coding:utf-8 -*-
# __author__=LuLu

import os
import time
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait  # 注意这个EC导包
from selenium.webdriver.support import expected_conditions as EC
from comment.Tools import is_contains_chinese, sleep, get_dirabspath, select_pic
from comment.readYaml import ReadYaml
from pagesLocators.loginLocators import LoginLoc
from pagesLocators.selectBoxLocators import SelectBoxLoc as selectLoc


class BasePage(ReadYaml):
    # 初始化
    def __init__(self, driver):
        self.driver = driver
        # self.driver.maximize_window()

    # 封装定位方式
    def find_element(self, *args):
        try:
            # return WebDriverWait(self.driver, 5, 0.5).until(EC.visibility_of_element_located(*args))  # 显形等待
            return WebDriverWait(self.driver, 5, 0.5).until(EC.presence_of_element_located(*args))  # 隐形等待
        except Exception as e:
            print(f'定位不到指定元素:{args}')
            raise e

    def find_element_visibility(self, *args):
        try:
            return WebDriverWait(self.driver, 5, 0.5).until(EC.visibility_of_element_located(*args))  # 显形等待
            # return WebDriverWait(self.driver, 10, 0.5).until(EC.presence_of_element_located(*args))  # 隐形等待
        except Exception as e:
            print(f'定位不到指定元素:{args}')
            raise e

    # 可能存在多个元素的定位方式
    def find_elements(self, *loc):
        try:
            # return WebDriverWait(self.driver, 5, 0.5).until(EC.visibility_of_any_elements_located(*loc))
            return WebDriverWait(self.driver, 5, 0.5).until(EC.presence_of_all_elements_located(*loc))
        except Exception as e:
            raise e

    # 打开网址
    def visit_url(self, url=ReadYaml().get_host()):
        self.driver.get(url)

    '''元素操作封装 '''

    # 移动到对应元素
    def move_to_element(self, element):
        """

        :param element:
        :return:
        .perform() 这个参数不能不加，否则找不到对应的参数
        """
        ActionChains(self.driver).move_to_element(self.find_element(element)).perform()

    # 点击元素
    def click_element(self, element):
        self.find_element(element).click()

    # 元素输入
    def sendKey_element(self, element, values):
        self.find_element(element).send_keys(values)

    # 获取元素的值
    def get_element_value(self, element):
        try:
            return self.find_element_visibility(element).text
        except Exception as e:
            print("无法进行查找页面上显示的元素的值")
            raise e

    # 清空元素
    def clear_element(self, element):
        self.find_element(element).clear()

    # 清空并重新键入元素
    def clear_and_sendKey_element(self, element, values):
        self.clear_element(element)
        self.sendKey_element(element, values)

    # 修改attribute的属性值，执行js脚本
    # DOM参考地址 https://www.runoob.com/jsref/dom-obj-all.html
    # def execute_script_toChange(self, script, element):
    #     self.driver.execute_script(script, self.find_element(element))

    # 删除attribute属性-js
    def remove_execute_script(self, value, element):
        try:
            self.driver.execute_script(f'arguments[0].removeAttribute(\"{value}\")', self.find_element(element))
        except:
            print(f'元素{element}没有{value}属性')

    # 设置attribute属性-js
    def set_value_execute_script(self, key, value, element):
        try:
            self.driver.execute_script(f'arguments[0].setAttribute(\"{key}\",\"{value}\")', self.find_element(element))
        except:
            print(f'元素{element}没有{key}属性,赋值失败')

    # 获取table列表数据，保存为list
    def list_content(self, element):
        table = self.find_element(element)
        rows = table.find_elements_by_tag_name("tr")
        row_name = []
        for row in rows:
            # 这里存在时间的话会被切分为2个日期和时间，
            row_name.append(row.text.split())
        return row_name

    # 读取tab的的指定行，传入参数为指定的table元素定位，row_num为指定多少条，1为起始
    def get_table_row(self, element, start_row=None, row_num=None):
        if row_num is not None and start_row is not None:
            return self.list_content(element)[start_row - 1:row_num]
        elif start_row is not None:
            return self.list_content(element)[start_row - 1:]
        else:
            return self.list_content(element)

    # 读取tab的指定列，传入参数为指定的table元素定位，和第N列
    def get_table_line(self, element, start_line=1, line_num=None):
        lines = []
        for i in self.list_content(element):
            lines.append(i[start_line - 1])
        if line_num is not None and start_line is not None:
            return lines[start_line - 1:line_num]
        else:
            # print(lines)
            return lines

    def page_num(self, PageNumElement, tableList):
        if self.isElementExist(PageNumElement):
            str_value = self.get_element_value(PageNumElement)
            if is_contains_chinese(str_value):
                # print('中文翻页')
                return int(str_value.replace(f'显示第 1 到第 {len(self.get_table_row(tableList))} 条记录，总共', '').
                           replace('条记录', '').strip())
            else:
                # 加载为英文时
                # print('英文翻页')
                return int(str_value.replace(f'Showing 1 to {len(self.get_table_row(tableList))} of', '').
                           replace('rows per page', '').strip())
        else:
            print("数据<10,不存在翻页")
            return 0

    # 上传图片
    def uploading_picture(self, element, *fileName):
        path = get_dirabspath() + '\\comment\\upload.exe '
        self.click_element(element)
        sleep(2.50)
        os.system(path + select_pic(*fileName))
        print(f'选择上传---->{path + select_pic(*fileName)}')
        sleep(1.0)

    # 点击bar导航栏
    def click_navigation(self, main_bar, next_bar):
        self.move_to_element(main_bar)
        sleep(1)
        self.click_element(next_bar)
        self.driver.implicitly_wait(5)
        sleep(1)

    # 获取某个元素的属性
    def get_element_attribute(self, element, attribute):
        try:
            return self.find_element(element).get_attribute(attribute)
        except Exception as e:
            print(f'获取{element}-->{attribute}属性失败！')
            raise e

    # 重写switch_frame方法
    def switch_frame(self, element):
        self.driver.switch_to.frame(self.find_element(element))

    # 获取网址标题
    def get_title(self):
        return self.driver.title

    # 获取网址url
    def get_url(self):
        return self.driver.current_url

    '''断言封装'''

    # 校验是否为真
    @staticmethod
    def assert_True(key):
        assert key is True

    # 校验是否为假
    @staticmethod
    def assert_False(key):
        assert key is not False

    # 校验是否相等
    @staticmethod
    def assert_Equal(key1, key2, *hint):
        try:
            assert key1 == key2, hint
        except Exception as e:
            print(f'key1:{key1} --不同于-->  key2:{key2}')
            raise e

    # 校验是否不相等
    @staticmethod
    def assert_Not_Equal(key1, key2):
        try:
            assert key1 != key2
        except Exception as e:
            print(f'key1:{key1} --同于-->  key2:{key2}')
            raise e

    # 校验页面是否存在某字符串
    def check_exist_in_page(self, someStr):
        self.assert_True(someStr in self.driver.page_source)

    # 判断是否存在该元素
    def isElementExist(self, element):
        flag = True
        try:
            self.find_element_visibility(element)
            return flag
        except Exception as e:
            print("↑↑处理以上异常，用于判断元素是否存在，正常打印定位不到元素信息↑↑")
            flag = False
            return flag

    def refresh(self):
        self.driver.refresh()

    # 基础登录
    def base_login(self, name=ReadYaml().get_username(), password=ReadYaml().get_password()):
        """作为测试其他页面的基础"""
        self.visit_url(f'{ReadYaml().get_host()}/ucenter/login')
        self.clear_element(LoginLoc.user_name)
        self.sendKey_element(LoginLoc.user_name, name)
        time.sleep(0.5)
        self.clear_element(LoginLoc.password)
        self.sendKey_element(LoginLoc.password, password)
        time.sleep(0.5)
        # self.input_auth_key(auth_key)
        self.click_element(LoginLoc.login_button)

    """
    表格通用多选/单选方法封装
    """

    # 单选
    def select_one(self, num):
        self.click_element(selectLoc.select_one_box(num))

    # 全选
    def select_all(self):
        self.click_element(selectLoc.select_all)
